import {encrypt, existValue, getCurrentTime, getMD5, parseFenDropHistory, str2hex} from "@/lib/utils";
import Sqlite, {ESqliteDBHandler} from "@/lib/sqlite";


export default new class Database {
  // 查询某个fen是否存在，存在则返回所有的棋步
  async searchFen(fen: string): Promise<any> {
    fen = parseFenDropHistory(fen)
    if (!Sqlite.dbHandler) return []
    try {
      const md5 = getMD5(fen)
      const sql = `select * from data where md5 = "${md5}"`
      const res = await Sqlite.select(sql, ESqliteDBHandler.db)
      return res
    } catch (err) {
      console.log("err", err)
      return []
    }
  }

  // 查询某一步棋是否存在，存在则返回数据
  async searchMove(fen: string, move: string): Promise<any> {
    fen = parseFenDropHistory(fen)
    if (!Sqlite.dbHandler) return []
    try {
      const md5 = getMD5(fen)
      const sql = `select * from data where md5 = "${md5}" and move="${move}"`
      const res = await Sqlite.select(sql, ESqliteDBHandler.db)
      return res
    } catch (err) {
      console.log("err", err)
      return []
    }
  }

  // 仅判断一步棋是否存在
  async existMove(fen: string, move: string): Promise<boolean> {
    fen = parseFenDropHistory(fen)
    if (!Sqlite.dbHandler) return false
    try {
      const md5 = getMD5(fen)
      const sql = `select * from data where md5 = "${md5}" and move = "${move}"`
      const res = await Sqlite.select(sql, ESqliteDBHandler.db)
      return res?.length > 0;

    } catch (err) {
      console.log("err", err)
      return false
    }
  }

  async saveFen(params: {
    fen: string,
    value: string,
    move: string,
    createTime: number,
    name: string,
    nameEn: string
  }, config?: { updateName: boolean }): Promise<any> {
    try {
      params.fen = parseFenDropHistory(params.fen)
      const md5 = getMD5(params.fen)
      const {fen, value, move, createTime, name, nameEn} = params
      const sql = `insert into data (fen, md5, name, nameEn, value,  move, createTime)` +
        `values("${fen}","${md5}","${name}","${nameEn}","${value}","${move}","${createTime}")`
      const sqlSelect = `select * from data where fen = "${fen}" and  move="${ move}"`
      const history = await Sqlite.select(sqlSelect, ESqliteDBHandler.db)
      if (history.length > 0) {
        // 插入变更新
        let sqlUpdate: string = null
        // 是否更新局面名称
        if (config?.updateName !== false) {
          sqlUpdate = `update data set name = "${name}", nameEn = "${nameEn}", value="${value}", createTime = "${getCurrentTime()}" where fen = "${fen}" and move="${move}"`
        } else {
          sqlUpdate = `update data set value="${value}", createTime = "${getCurrentTime()}" where fen = "${fen}" and move="${move}"`
        }
        await Sqlite.update(sqlUpdate)
        return
      }
      await Sqlite.insert(sql)
      return
    } catch (err) {
      console.log("err", err)
    }
  }

  async deleteFen(fen: string, move: string = null): Promise<any> {
    try {
      fen = parseFenDropHistory(fen)
      const md5 = getMD5(fen)
      let sql = ''
      if (move) {
        sql = `delete from data where md5 = "${md5}" and  move ="${move}"`
      } else {
        sql = `delete from data where md5 = "${md5}"`
      }
      await Sqlite.delete(sql, ESqliteDBHandler.db)
      return
    } catch (err) {
      console.log("err", err)
    }
  }

  async searchByName(name: string, selectOpen: string): Promise<any> {
    let sql
    if (name !== '' && !selectOpen) {
      sql = `select * from data where name like "%${name}%" or nameEn like "%${name}%"`

    } else if ((name === '' || !name) && selectOpen) {
      sql = `select * from data where nameEn like "${selectOpen}%"`
    } else {
      sql = `select * from data where name like "%${name}%" or nameEn like "%${name}%" and nameEn like "${selectOpen}%"`
    }
    const res = await Sqlite.select(sql)
    return res
  }

  async close(): Promise<any> {
    await Sqlite.close()
  }

  // 新增或者保存开局
  async updateOpening(name: string, subName: string, data: any): Promise<any> {
    const selectSql = `select * from opening where name = "${name}" and subName = "${subName}"`
    data = encrypt(data)
    const exist = await Sqlite.select(selectSql, ESqliteDBHandler.tutorial)
    let sql
    if (exist?.length > 0) {
      sql = `update opening set data = '${data}' where name = "${name}" and subName = "${subName}"`
    } else {
      sql = `insert into opening(name, subName, data) values ("${name}", "${subName}", '${data}')`
    }
    await Sqlite.dbOp(sql, ESqliteDBHandler.tutorial)
    return
  }

  async getOpeningGroup(regex?: string): Promise<{ name: string }[]> {
    let sql = `select distinct name from opening`
    if (regex) {
      sql += ` where name like "%${regex}%"`
    }
    sql += ` order by subName`
    return Sqlite.select(sql, ESqliteDBHandler.tutorial)
  }

  async getOpening(name: string, star: number=null): Promise<any> {
    let sql = null
    if (name !== '') {
      sql = `select * from opening where name = "${name}" `
      if (star) sql += ` and star = '${Number(star)}'`
      sql+= ` order by subName`
    } else {
      sql = `select * from opening`
      if (star) sql += ` where star = '${Number(star)}'`
      sql += ` order by RANDOM() limit 30`
    }

    return Sqlite.select(sql, ESqliteDBHandler.tutorial)
  }

  async getRandomOpening(): Promise<any> {
    const sql = `select * from opening order by RANDOM() limit 30`
    return Sqlite.select(sql, ESqliteDBHandler.tutorial)
  }

  // 编辑开局名称
  async editOpeningName(name: string, subName: string, newName: string, newSubName: string): Promise<any> {
    const sql = `update opening set name = "${newName}", subName = "${newSubName}" where name = "${name}" and subName = "${subName}"`
    console.log("sql", sql)
    await Sqlite.dbOp(sql, ESqliteDBHandler.tutorial)
    return
  }


  async saveOpeningStar(name: string, subName: string, star: any): Promise<any> {
    let sql = `update opening set star = ${Number(star)} where name = "${name}" and subName = "${subName}"`
    console.log("sql", sql)
    await Sqlite.dbOp(sql, ESqliteDBHandler.tutorial)
    return
  }


  // 棋局模块

  // 获取棋局的集合
  async getGameCollect(keyword?: string): Promise<any> {
    let sql = `select * from collect`
    if (keyword) {
      sql += ` where name like "%${keyword}%"`
    }
    return Sqlite.select(sql, ESqliteDBHandler.game)
  }

  async getMaxSortCodeFromCollect(): Promise<any> {
    let sql = `select sortCode from collect order by sortCode desc limit 1`
    return Sqlite.select(sql, ESqliteDBHandler.game)
  }

  async getMaxSortCodeFromGame(hashName: string): Promise<any> {
    let sql = `select sortCode from game where hashName = '${hashName}' order by sortCode desc limit 1`
    return Sqlite.select(sql, ESqliteDBHandler.game)
  }

  // 保存棋局的集合名
  async saveGameCollect(data: { name: string, description: string, source: string, sourceInfo: string }): Promise<any> {
    const hashName = encrypt(data.name)
    const maxCode = await this.getMaxSortCodeFromCollect()
    const sortCode = Number(maxCode?.[0]?.sortCode || 0) + 1
    let exist = `select * from collect where hashName = "${hashName}"`
    const count = await Sqlite.select(exist, ESqliteDBHandler.game)
    console.log("count", count)
    if (count?.[0]) return false

    let sql = `insert into collect (hashName, name, source,  sourceInfo, createAt, sortCode) 
        values ("${hashName}", "${data.name}", "${data.source}", "${data.sourceInfo}", "${getCurrentTime()}", "${sortCode}")`
    console.log("sql", sql)
    await Sqlite.dbOp(sql, ESqliteDBHandler.game)
    return true
  }

  // 编辑棋局的集合
  async editGameCollect(oldName: string, data: {
    name: string,
    description: string,
    source: string,
    sourceInfo: string
  }): Promise<any> {
    const hashName = encrypt(data.name)
    const oldHash = encrypt(oldName)
    let sql = `update collect set hashName = "${hashName}", name="${data.name}", 
    source="${data.source}", sourceInfo="${data.sourceInfo}", createAt="${getCurrentTime()}" where  hashName = "${oldHash}"`
    await Sqlite.dbOp(sql, ESqliteDBHandler.game)
    // 需要更新对局表的hash值
    let gameSql = `update game set hashName = "${hashName}" where hashName="${oldHash}"`
    await Sqlite.dbOp(gameSql, ESqliteDBHandler.game)
    return true
  }

  // 根据合集名获取棋局
  async getGameList(hashName: string, opening: string=null, limit: number, offset: number): Promise<any> {
    let sql = `select hashName, white, black, result, opening, description, gameDate, data, sortCode, createAt from game where hashName = "${hashName}" `
    if (opening) sql += ` and opening = '${opening}' `
    sql += ` order by sortCode asc `
    sql += ` limit ${limit}`
    if (existValue(offset)) sql += ` offset ${offset}`
    console.log("sql", sql)
    const data = await Sqlite.select(sql, ESqliteDBHandler.game)
    let countSql = `select count(*) as count from game where hashName = '${hashName}' `
    if (opening) countSql += ` and opening = '${opening}' `
    const count = await Sqlite.select(countSql, ESqliteDBHandler.game)
    return {count, data}
  }

  // 保存局面
  async saveGame(hashName: string, gameInfo: {
                   white: string, black: string, description: string, result: '1-0' | '0-1' | '1/2-1/2',
                   opening: string, gameDate: string,
                   gameData:
                     {
                       move: string, description: string,
                       childData: {
                         data: {
                           move: string, description: string
                         }[]
                       }[]
                     }[]
                 }, editSortCode: number
  ): Promise<any> {
    const {white, black, description, result, opening, gameDate, gameData} = gameInfo
    const newData = str2hex(JSON.stringify(gameData))
    const maxCode = await this.getMaxSortCodeFromGame(hashName)
    const sortCode = editSortCode || Number(maxCode?.[0]?.sortCode || 0) + 1
    let sql = `insert into game (hashName, white, black, description, result, opening, gameDate, data, sortCode, createAt) 
        values("${hashName}", "${white}", "${black}", "${description}", "${result}", "${opening}", "${gameDate}",
         "${newData}", "${sortCode}", "${getCurrentTime()}")`
    console.log("sql", sql)

    if (existValue(editSortCode)) {
      const deleteSql = `delete from game where sortCode='${editSortCode}' and hashName = '${hashName}'`
      await Sqlite.dbOp(deleteSql, ESqliteDBHandler.game)
      console.log("deleteSql", deleteSql)
    }

    await Sqlite.dbOp(sql, ESqliteDBHandler.game)
    let mainSql = `update  collect set createAt = '${getCurrentTime()}' where hashName = '${hashName}'`
    await Sqlite.dbOp(mainSql, ESqliteDBHandler.game)

    return true
  }

  async getGameOpeningDistinct(hashName: string): Promise<any> {
    const sql = `select distinct opening from game where hashName = '${hashName}'`
    return Sqlite.select(sql, ESqliteDBHandler.game)
  }

  async deleteGame(sortCode: number): Promise<any> {
    const deleteSql = `delete from game where sortCode="${sortCode}"`
    await Sqlite.dbOp(deleteSql, ESqliteDBHandler.game)
    console.log("deleteSql", deleteSql)

    await Sqlite.dbOp(deleteSql, ESqliteDBHandler.game)
    return true
  }

  // 计算每个合集一共有多少棋局
  async countGameInCollect(): Promise<any> {
    const sql = `select count(*) as count, hashName from game group by hashName`
    return Sqlite.select(sql, ESqliteDBHandler.game)
  }

  // 入库用户对局
  async saveUserGame(gameInfo: {
    event: string,
    type: string,
    date: string,
    opening: string,
    white: string,
    black: string,
    result: string,
    whiteElo: string,
    blackElo: string,
    time: string,
    hash: string,
    data: { [key: string]: any }[]
  }): Promise<any> {
    const data = str2hex(JSON.stringify(gameInfo.data))
    let sql = `insert into game(hash, event, type, white, black, whiteElo, blackElo, result, opening, gameDate, data, analyzed, time) 
    values("${gameInfo.hash}", "${gameInfo.event}", "${gameInfo.type}", "${gameInfo.white}", "${gameInfo.black}", 
    "${gameInfo.whiteElo}", "${gameInfo.blackElo}", "${gameInfo.result}", "${gameInfo.opening}", "${gameInfo.date}", "${data}", 0, "${gameInfo.time}")`
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    return true
  }

  async findGameByHash(hash: string): Promise<any> {
    let sql = `select count(1) as count from game where hash = "${hash}"`
    return Sqlite.select(sql, ESqliteDBHandler.user)
  }

  async getGameByPage(limit: number, offset: number, cond?: {
    type: string, time: string, order: 'desc' | 'asc',
    orderByKey: string, gameDate: number, result: 'win' | 'lose' | 'draw', userName: string, analyze: 0 | 1
  }): Promise<{ count: number, data: any[] }> {
    let orderByKey = 'gameDate'
    if (cond?.orderByKey) orderByKey = cond.orderByKey
    let order = 'desc'
    if (cond?.order) order = cond.order
    let where = false // 需不需要where条件
    let sql = `select * from game `
    let countSql = `select count(1) as count from game`

    // 根据条件组成sql的后缀
    let tail = ` `
    if (cond?.time) {
      const temp = where ? ` and time = "${cond.time}"` : `where time = "${cond.time}" `
      tail += temp
      where = true
    }
    if (cond?.type) {
      const temp = where ? ` and type = "${cond.type}"` : `where type = "${cond.type}" `
      tail += temp
      where = true
    }
    if (cond?.gameDate) {
      const temp = where ? ` and gameDate >= ${cond.gameDate}` : `where gameDate >= ${cond.gameDate} `
      tail += temp
      where = true
    }
    if (cond?.result) {
      if (cond.result === 'draw') {
        const temp = where ? ` and (result <> '1-0' and result <> '0-1')` : ` where (result <> '1-0' and result <> '0-1') `
        tail += temp
        where = true
      }
      if (cond.result === 'win') {
        const temp = where ? ` and ((result = '1-0' and white = '${cond.userName}') or (result = '0-1' and black = '${cond.userName}'))` :
          ` where ((result = '1-0' and white = '${cond.userName}') or (result = '0-1' and black = '${cond.userName}'))`
        tail += temp
        where = true
      }
      if (cond.result === 'lose') {
        const temp = where ? ` and ((result = '0-1' and white = '${cond.userName}') or (result = '1-0' and black = '${cond.userName}'))` :
          ` where ((result = '0-1' and white = '${cond.userName}') or (result = '1-0' and black = '${cond.userName}'))`
        tail += temp
        where = true
      }
    }
    if (existValue(cond?.analyze) && (cond.analyze === 0 || cond.analyze === 1)) {
      const temp = where ? ` and analyzed = "${cond.analyze}"` : ` where analyzed = "${cond.analyze}" `
      tail += temp
      where = true
    }
    sql += tail
    // 最后拼接末尾
    sql += `order by ${orderByKey}  ${order} limit ${limit}`
    if (existValue(offset)) sql += ` offset ${offset}`

    countSql += tail
    console.log("sql", sql)

    const data = await Sqlite.select(sql, ESqliteDBHandler.user)
    const count = await Sqlite.select(countSql, ESqliteDBHandler.user)
    console.log("count", count)
    return {count, data}
  }

  // 获取有多少种时间和比赛类型
  async getTypeAndTimeFromGame(): Promise<{ time: any, type: any }> {
    let timeSql = `select distinct time from game order by time asc`
    let gameSql = `select distinct type from game order by type asc`
    const time = await Sqlite.select(timeSql, ESqliteDBHandler.user)
    const game = await Sqlite.select(gameSql, ESqliteDBHandler.user)
    return {time, type: game}
  }

  async getLastUserGame(): Promise<any> {
    let sql = `select gameDate from game order by gameDate desc limit 1`
    return Sqlite.select(sql, ESqliteDBHandler.user)
  }

  async getAllUserGame(): Promise<any> {
    let sql = `select * from game order by gameDate asc`
    return Sqlite.select(sql, ESqliteDBHandler.user)
  }

  // 保存分析结果
  async saveAnalyzeResult(gameInfo: { hash: string }, gameData: any[]): Promise<any> {
    let sql = `update game set analyzed = 1, data = "${str2hex(JSON.stringify(gameData))}" where hash = "${gameInfo.hash}"`
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    return true
  }

  async getNotAnalyzedGame(): Promise<any> {
    let sql = `select * from game where analyzed = "0" order by gameDate desc`
    return Sqlite.select(sql, ESqliteDBHandler.user)
  }

  async getExercise(hash: string): Promise<any> {
    const sql = `select * from exercise where hash = "${hash}" order by value desc`
    return Sqlite.select(sql, ESqliteDBHandler.user)
  }

  async saveExercise(data: {
                       hash: string,
                       fenHash?: string,
                       badMove?: string,
                       correctMove?: string,
                       value?: any,
                       learn: 0 | 1,
                       type: '错着' | '败着' | '不精确',
                       disabled: 0 | 1,
                       moveNum: number,
                       analyzed: 0,
                     },
                     gameData: { white: string, black: string, gameDate: string, gameType: string }): Promise<any> {
    const {
      hash,
      fenHash,
      badMove,
      correctMove,
      value,
      learn,
      type,
      disabled,
      moveNum,
      analyzed,

    } = data
    const {
      white,
      black,
      gameDate,
      gameType
    } = gameData
    const sql = `insert into exercise (hash, fenHash, badMove, correctMove, value, learn, type, disabled, moveNum,
  analyzed, white, black, gameDate, gameType, correct, wrong ) 
        values("${hash}", "${fenHash}", "${badMove}", "${correctMove}", "${value}", "${learn}", "${type}", "${disabled}", 
        "${moveNum}",  "${analyzed}", "${white}", "${black}", "${gameDate}", "${gameType}", 0, 0)`
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    console.log("sql", sql)
    return true
  }

  // 入库错题之前先进行清理
  async clearExercise(hash: string): Promise<any> {
    let sql = `delete from exercise where hash = "${hash}"; vacuum;`
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    return true
  }

  // 禁用习题
  async disableExercise(fenHash: string, moveNum: number): Promise<any> {
    let sql = `update exercise set disabled = 1 where fenHash = "${fenHash}" and moveNum = "${moveNum}" `
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    return true
  }

  // 随机获取题目
  async getRandomExercise(limit: number, offset: number): Promise<any> {
    const countSql = `select count(1) as count from exercise `
    const count = await Sqlite.select(countSql, ESqliteDBHandler.user)
    const sql = `select * from exercise order by RANDOM() limit ${limit} offset ${offset}`
    const data = await Sqlite.select(sql, ESqliteDBHandler.user)
    console.log("sql", sql)
    return {count, data}
  }

  async getExerciseByPage(limit: number, offset: number, cond?: {
    type?: string, gameType?: string, order?: 'desc' | 'asc',
    gameDate?: number, isMe?: boolean, userName?: string,
    analyze?: 0 | 1, learn?: 0 | 1, disabled?: 0 | 1, notPage?: boolean, random?: boolean
  }): Promise<{ count: number, data: any[] }> {
    let orderByKey = 'gameDate'
    let order = 'desc'
    if (cond?.order) order = cond.order
    let where = false // 需不需要where条件
    let sql = `select * from exercise `
    let countSql = `select count(1) as count from exercise`

    // 根据条件组成sql的后缀
    let tail = ` `
    if (cond?.type) {
      const temp = where ? ` and type = "${cond.type}"` : `where type = "${cond.type}" `
      tail += temp
      where = true
    }

    if (cond?.gameType) {
      const temp = where ? ` and gameType = "${cond.gameType}"` : `where gameType = "${cond.gameType}" `
      tail += temp
      where = true
    }
    if (cond?.gameDate) {
      const temp = where ? ` and gameDate >= ${cond.gameDate}` : `where gameDate >= ${cond.gameDate} `
      tail += temp
      where = true
    }

    if (existValue(cond?.analyze) && (cond.analyze === 0 || cond.analyze === 1)) {
      const temp = where ? ` and analyzed = ${cond.analyze}` : ` where analyzed = ${cond.analyze} `
      tail += temp
      where = true
    }
    if (existValue(cond?.learn) && (cond.learn === 0 || cond.learn === 1)) {
      const temp = where ? ` and learn = ${cond.learn}` : ` where learn = ${cond.learn} `
      tail += temp
      where = true
    }
    if (existValue(cond?.disabled) && (cond.disabled === 0 || cond.disabled === 1)) {
      const temp = where ? ` and disabled = ${cond.disabled}` : ` where disabled = ${cond.disabled} `
      tail += temp
      where = true
    }


    if (cond?.random) {
      sql += ` order by RANDOM() limit 1`
    } else {
      sql += tail
    }

    if (!cond?.notPage && !cond?.random) {
      // 最后拼接末尾
      sql += ` order by ${orderByKey}  ${order} limit ${limit}`
      if (existValue(offset)) sql += ` offset ${offset}`
    } else if (cond?.notPage && !cond?.random) {
      // 查询的时候先打乱一次，做题的时候就避免一局棋反复做题
      sql += ` order by RANDOM()`
    }


    countSql += tail
    console.log("sql", sql)

    const data = await Sqlite.select(sql, ESqliteDBHandler.user)
    const count = await Sqlite.select(countSql, ESqliteDBHandler.user)
    return {count, data}
  }

  async getDistinctTypeFromExercise(): Promise<any> {
    let sql = `select distinct gameType from exercise`
    return await Sqlite.select(sql, ESqliteDBHandler.user)
  }

  // 禁用多个习题
  async disabledExerciseByCond(cond?: {
    gameType: string,
    type: string,
    order: 'desc' | 'asc',
    gameDate: number,
    isMe: boolean,
    userName: string,
    analyze: 0 | 1,
    learn: 0 | 1,
    disabled: 0 | 1,
    disableStatus: 0 | 1
  }): Promise<any> {
    let countSql = `select count(*) as count from exercise `
    let sql = `update exercise set disabled = ${cond.disableStatus}`
    let where = false // 需不需要where条件
    // 根据条件组成sql的后缀
    let tail = ` `
    if (cond?.type) {
      const temp = where ? ` and type = "${cond.type}"` : `where type = "${cond.type}" `
      tail += temp
      where = true
    }

    if (cond?.gameType) {
      const temp = where ? ` and gameType = "${cond.gameType}"` : `where gameType = "${cond.gameType}" `
      tail += temp
      where = true
    }
    if (cond?.gameDate) {
      const temp = where ? ` and gameDate >= ${cond.gameDate}` : `where gameDate >= ${cond.gameDate} `
      tail += temp
      where = true
    }

    if (existValue(cond?.analyze) && (cond.analyze === 0 || cond.analyze === 1)) {
      const temp = where ? ` and analyzed = ${cond.analyze}` : ` where analyzed = "${cond.analyze}" `
      tail += temp
      where = true
    }
    if (existValue(cond?.learn) && (cond.learn === 0 || cond.learn === 1)) {
      const temp = where ? ` and learn = ${cond.learn}` : ` where learn = "${cond.learn}" `
      tail += temp
      where = true
    }
    if (existValue(cond?.disabled) && (cond.disabled === 0 || cond.disabled === 1)) {
      const temp = where ? ` and disabled = ${cond.disabled}` : ` where disabled = ${cond.disabled} `
      tail += temp
      where = true
    }

    // 不允许修改不带条件
    if (!where) return -1

    sql += tail
    countSql += tail
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    const count = await Sqlite.select(countSql, ESqliteDBHandler.user)
    return count[0]?.count || 0
  }

  async getGameInfoByHash(hash: string): Promise<any> {
    let sql = `select * from game where hash = "${hash}" `
    const res =  await Sqlite.select(sql, ESqliteDBHandler.user)
    return res[0] || null
  }

  // 按条件获取数据，不考虑分页
  async getExerciseForLearn(cond?: {
    type?: string, gameType?: string, order?: 'desc' | 'asc',
    gameDate?: number, isMe?: boolean, userName?: string, analyze?: 0 | 1,
    learn?: 0 | 1, disabled?: 0 | 1, notPage?: boolean,
    random?: boolean,
  }): Promise<any> {
    cond.notPage = true
    // TODO 是否需要考虑limit?
    return await this.getExerciseByPage(0, 0, cond)
  }

  async getOneExerciseForLearn(cond?: {
    type?: string, gameType?: string, order?: 'desc' | 'asc',
    gameDate?: number, isMe?: boolean, userName?: string, analyze?: 0 | 1, learn?: 0 | 1,
    disabled?: 0 | 1, notPage?: boolean, random?: boolean
  }): Promise<any> {
    cond.notPage = true
    cond.random = true
    // TODO 是否需要考虑limit?
    return await this.getExerciseByPage(0, 0, cond)
  }

  // 更新答题的结果
  async recordExerciseResult(hash: string, fenHash: string, result: -1 | 1): Promise<any> {
    let sql = `update exercise `
    let tail = ''
    if (result === 1) {
      tail = `set learn = 1, correct = correct + 1`
    } else {
      tail = `set learn = 1, wrong = wrong + 1`
    }
    sql += tail + ` where hash = "${hash}" and fenHash = "${str2hex(fenHash)}"`
    console.log("sql", sql)
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    return true
  }

  // 获取单个习题
  async getSingleExercise(hash: string, fenHash: string, moveNum: number): Promise<any> {
    let sql = `select * from exercise where hash = "${hash}" and fenHash = "${fenHash}" 
        and moveNum = "${moveNum}"`
    return await Sqlite.select(sql, ESqliteDBHandler.user)
  }

  // 更新单个习题的分析结果
  async updateExerciseAnalyzeResult(hash: string, fenHash: string, moveNum: number, correctMove: string, value: number): Promise<any> {
    let sql = `update exercise set correctMove = "${correctMove}", value = "${value}", analyzed = 1  where hash = "${hash}" and fenHash = "${fenHash}" and moveNum = "${moveNum}"`
    console.log("sql", sql)
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    return true
  }

  // 删除某个习题，因为分析的结果更精确了
  async deleteExercise(hash: string, fenHash: string, moveNum: number): Promise<any> {
    const sql =  `delete from exercise where hash = "${hash}" and fenHash = "${fenHash}" and moveNum = "${moveNum}" `
    console.log("sql", sql)
    await Sqlite.dbOp(sql, ESqliteDBHandler.user)
    return true
  }
}